package XYC;

import java.awt.geom.Point2D;
import robocode.Robot;

/**
 * A new subclass of robot that has some new functionalities.
 * Code original written by Aaron Herres.
 * @author Yichi Xu
 * */
public class YichiRobot extends Robot {
/**
* Move the robot to a specific location.
* @param location a Point2D object that indicates the target location
* No output
**/
  protected void moveToPoint(Point2D location) {
    moveTowards(getHeadingTo(location),location.distance(getCurrentPos()));
  }
/**
* Move the robot towards a direction with a certain speed.
* @param heading a double instance that indicates the direction in degree
* @param speed a double instance that indicates the speed
* No output
* */
  protected void moveTowards(double heading, double speed) {
    turnRight(RoboCodeUtil.normalizeHeading(heading));
    ahead(speed);
  }
/**
* Move the robot in a circle.
* @param center a Point2D object that indicates the center of the circle
* @param angle a double instance that indicates the angle that robot turns each turn
* No output
* */
  protected void moveInCircle(Point2D center, double angle) {
    double radius = center.distance(getCurrentPos());
    for (int i = 0; i < 360; i += angle) {
      double tempX = center.getX() + radius * Math.sin(i * Math.PI / 180);
      double tempY = center.getY() + radius * Math.cos(i * Math.PI / 180); 
      Point2D tempPoint = new Point2D.Double(tempX, tempY);
      moveToPoint(tempPoint);
    }
  }
/**
* Return the center of current battlefield.
* No input.
* @return a Point2D object that contains the center of the battlefield
* */
  protected Point2D getCenter() {
    return new Point2D.Double(getBattleFieldWidth() / 2, getBattleFieldHeight() / 2);
  }
/** 
* Return the current location.
* No input
* @return a Point2D object that contains robot's current location
* */
  protected Point2D getCurrentPos() {
    return new Point2D.Double(getX(), getY());
  }
/**
* Return in degree that robot should head to in order to reach the target.
* @param location a Point2D object that indicates the target location
* @return a double instance that indicates the supposed heading in degree
* */
  protected double getHeadingTo(Point2D location) {
    return  RoboCodeUtil.computeHeading(location, getCurrentPos(), getHeading());
  }
/**
 * Return in degree that robot's gun should head to in order to shoot at the target.
 * @param location a Point2D object that indicates the target location
 * @return a double instance that indicates the supposed heading in degree
 * */
  protected double getGunHeadingTo(Point2D location) {
    return  RoboCodeUtil.computeHeading(location, getCurrentPos(), getHeading());
  }
/**
 * Fire a bullet with certain power to a location.
 * @param location a Point2D object that indicates the target location
 * @param power a double instance that indicates the power of the bullet 
 * No Output.
 * */
  protected void fireAt(Point2D location, double power) {
    turnGunRight(getGunHeadingTo(location));
    fire(power);
  }
}